package bot;
import bot.ClientFields;
import java.applet.Applet;
import java.applet.AppletContext;
import java.applet.AppletStub;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.MalformedURLException;
import java.net.JarURLConnection;
import java.util.HashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.io.File;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ClientLoader implements AppletStub {

	private static final HashMap<String, String> parameters = new HashMap<String, String>();
	public static int worldID = 2;
	public static Applet applet;
	public static Object client;
	public static Class clientClass;
	public static Class npcCache;
	public static ClassLoader clientClassLoader;

	public void appletResize(int x, int y) {
	}

	public boolean isActive() {
		return true;
	}

	public ClientLoader() throws Exception {

		parseForSettings();

		/*
		 * Notice that we load the client directly, without a loader. This is
		 * not unsafe and doesn't result in your character getting banned as RLN
		 * claimed back in 2009. You see, Jagex offer two clients: 'signed' and
		 * 'unsigned'. Unsigned clients have fewer permissions and can't store
		 * stuff on your hard disk (which is why the cache is loaded every
		 * single time). The unsigned client is loaded directly without
		 * loader.jar.
		 */

		/*
		 * Don't believe me?
		 * http://classic2.runescape.com/plugin.js?param=o0,a1,s0
		 */

		File fileLocation = new File("./rsclassic.jar");
		URL url = fileLocation.toURI().toURL();
		URL[] loaderURL = new URL[] { url };

		clientClassLoader = new URLClassLoader(loaderURL);
		clientClass = clientClassLoader.loadClass("client");
		npcCache = clientClassLoader.loadClass(ClientFields.npcCacheClass);
		client = clientClass.newInstance();

		applet = (Applet) (client);
		applet.setStub(this);
		applet.init();
		applet.start();
	}

	public URL getDocumentBase() {
		return this.getCodeBase();
	}

	public String getParameter(String name) {
		return parameters.get(name);
	}

	public AppletContext getAppletContext() {
		throw new UnsupportedOperationException();
	}

	/* Thanks to Meatstick + Waffle */
	public void parseForSettings() {
		try {
			URL url = new URL("http://classic" + worldID
					+ ".runescape.com/plugin.js?param=o0,a1,s0");
			BufferedReader br = new BufferedReader(new InputStreamReader(
					url.openStream()));
			String raw;

			while ((raw = br.readLine()) != null) {
				if (!raw.contains("param name") || !raw.contains("value")
						|| raw.contains("haveie6"))
					continue;

				raw = raw.replace("(", "");
				raw = raw.replace(")", "");
				raw = raw.replaceAll("document.write", "").replaceAll("\"", "")
						.replaceAll("'", "").replaceAll("<", "")
						.replaceAll(">", "").replaceAll(";", "");

				String param_name = null;
				String value = null;

				/*
				 * This is where the issue was, we needed to take a substring
				 * one character shorter for the crashurl and unsigned applet
				 * parameters
				 */

				if (raw.indexOf("param name") != -1
						&& raw.indexOf("value") != -1) {

					if (raw.contains("error_loader_crash")
							|| raw.contains("http://www.runescape.com/classicapplet/"))
						param_name = raw.trim().substring(
								"param_name=".length(),
								raw.indexOf("value") - 3);
					else
						param_name = raw.trim().substring(
								"param_name=".length(),
								raw.indexOf("value") - 2);

					raw = raw
							.substring(
									raw.indexOf(param_name)
											+ (param_name.length() + 1),
									raw.length());

					value = raw.trim().substring("value=".length(),
							raw.length());
					parameters.put(param_name, value);
					/* For debugging */
					System.out.println(param_name + ", " + value);
				}
			}
			/*
			 * Set this parameter once as opposed to every time the loop
			 * executes..
			 */
			parameters.put("haveie6", "0");
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	public URL getCodeBase() {
		try {
			return new URL("http://classic" + worldID + ".runescape.com/");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}